package com.kfm;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.math.BigDecimal;
import java.sql.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class BookManager {


    private final Scanner sc = new Scanner(System.in);

    public BookManager() {
        try {
            init();
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        } catch (SQLException e) {
            throw new RuntimeException(e);
        }
    }

    public void start() {
        try {
            menu();
        } catch (SQLException e) {
            throw new RuntimeException(e);
        } catch (ClassNotFoundException e) {
            throw new RuntimeException(e);
        }
    }

    private void menu() throws SQLException, ClassNotFoundException {
        System.out.println("****欢迎来到开发喵图书馆****");
        System.out.println("****请输入你要操作的选项****");
        System.out.println("1. 添加图书");
        System.out.println("2. 删除图书");
        System.out.println("3. 修改图书");
        System.out.println("4. 显示所有");
        int type = sc.nextInt();
        switch (type) {
            case 1 -> addBookInfo();
            case 2 -> removeBook();
            case 3 -> modifyBookQuantity();
            case 4 -> {
                List<Book> books = showAllBooks();
                System.out.println(books);
            }
        }
        menu();
    }


    private void init() throws ClassNotFoundException, SQLException {
        // 检测是否存在 books 以及 log
        String sql = "show tables";
        Connection conn = getConn();
        // 获取执行 sql 的对象
        Statement stat = conn.createStatement();
        // 执行sql
        ResultSet resultSet = stat.executeQuery(sql);
        List<String> list = new ArrayList<>();
        // 解析结果
        while (resultSet.next()) {
            list.add(resultSet.getString(1));
        }
        if (!(list.contains("books") && list.contains("log"))) {
            // 不存在就去读取文件
            String readSql = readSql();
            String[] strings = readSql.split(";");
            for (String s : strings) {
                int i = stat.executeUpdate(s);
            }
            close(conn);
        }
    }

    private String readSql() {
        try {
            FileInputStream in = new FileInputStream(new File("io\\sql.txt"));
            byte[] bytes = in.readAllBytes();
            String str = new String(bytes);
            return str;
        } catch (IOException e) {
            return "";
        }
    }

    /**
     * 添加图书
     *
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private void addBookInfo() throws SQLException, ClassNotFoundException {
        System.out.println("请输入图书名称");
        String name = sc.next();
        System.out.println("请输入图书出版日期");
        String date = sc.next();
        System.out.println("请输入图书作者");
        String author = sc.next();
        System.out.println("请输入图书价格");
        double price = sc.nextDouble();
        System.out.println("请输入图书数量");
        int quantity = sc.nextInt();
        String sql = String.format("insert into books(book_title, publication_date, author, price, quantity) " +
                "values('%s', '%s', '%s', %f, %d)", name, date, author, price, quantity);
        int i = executeUpdate(sql);
        if (i > 0) {
            System.out.println(colorInfo("插入" + name + "成功", 32));
            // TODO 添加 log
            java.util.Date d = new java.util.Date();
            addLog("插入" + name, d);
        } else {
            System.out.println("插入失败");
            System.out.println(colorInfo("插入" + name + "失败", 31));
        }
    }

    /**
     * 执行 insert update delete 操作
     *
     * @param sql
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private int executeUpdate(String sql) throws SQLException, ClassNotFoundException {
        Connection conn = getConn();
        Statement stat = conn.createStatement();
        int i = stat.executeUpdate(sql);
        close(conn);
        return i;
    }

    /**
     * 查询数据并放到list集合中
     *
     * @param sql
     * @return
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private List<Book> executeQuery(String sql) throws SQLException, ClassNotFoundException {
        Connection conn = getConn();
        Statement stat = conn.createStatement();
        ResultSet resultSet = stat.executeQuery(sql);
        List<Book> books = new ArrayList<>();
        while (resultSet.next()) {
            Book book = new Book();
            book.setId(resultSet.getInt("id"));
            book.setBookTitle(resultSet.getString("book_title"));
            book.setAuthor(resultSet.getString("author"));
            book.setPublicationDate(resultSet.getDate("publication_date"));
            book.setPrice(resultSet.getBigDecimal("price"));
            book.setQuantity(resultSet.getInt("quantity"));
            books.add(book);
        }
        close(conn);
        return books;
    }

    private <E> List<E> execute(String sql, Handler<E> handler) throws SQLException, ClassNotFoundException {
        Connection conn = getConn();
        Statement stat = conn.createStatement();
        ResultSet resultSet = stat.executeQuery(sql);
        List<E> list = new ArrayList<>();
        int count = resultSet.getMetaData().getColumnCount();
        Object[] objects = new Object[count];
        while (resultSet.next()) {
            // 构建出一个数组  数组里面放的是一行数据
            for (int i = 0; i < count; i++) {
                objects[i] = resultSet.getObject(i + 1);
            }

            E one = handler.getOne(objects);
            list.add(one);
        }
        return list;
    }


    public void test() throws SQLException, ClassNotFoundException {
        List<Book> execute = execute("select * from books", new Handler<Book>() {
            @Override
            public Book getOne(Object... objects) {
                Book book = new Book();
                book.setId((int) objects[0]);
                book.setBookTitle((String) objects[1]);
                book.setPublicationDate((Date) objects[2]);
                book.setAuthor((String) objects[3]);
                book.setPrice((BigDecimal) objects[4]);
                book.setQuantity((Integer) objects[5]);
                return book;
            }
        });

        List<Log> execute1 = execute("select * from log", new Handler<Log>() {
            @Override
            public Log getOne(Object... objects) {
                Log log = new Log();
                log.setLogId((Integer) objects[0]);
                log.setDescription((String) objects[1]);
                log.setOperationTime((Timestamp) objects[2]);
                return log;
            }
        });
    }


    /**
     * 删除图书
     *
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private void removeBook() throws SQLException, ClassNotFoundException {
        System.out.println("请输入要删除的图书名称");
        String title = sc.next();
        String sql = "delete from books where book_title = '" + title + "'";
        int i = executeUpdate(sql);
        if (i > 0) {
            System.out.println(colorInfo("删除" + title + "成功", 32));
            addLog("删除" + title, new java.util.Date());
        } else {
            System.out.println(colorInfo("删除" + title + "失败", 31));
        }
    }

    /**
     * 修改图书数量
     *
     * @throws SQLException
     * @throws ClassNotFoundException
     */
    private void modifyBookQuantity() throws SQLException, ClassNotFoundException {
        System.out.println("请输入图书名称");
        String title = sc.next();
        System.out.println("请输入要修改的数量");
        int quantity = sc.nextInt();
        // 查询到原来的数量 然后 比较 输入的数量
        String sql = "select * from books where book_title = '" + title + "'";
        List<Book> books = executeQuery(sql);// 查询图书信息
        int old = -1;
        // 判断图书是否存在
        if (books.size() > 0) {
            old = books.get(0).getQuantity();
        } else {
            System.out.println(colorInfo("要修改的" + title + "不存在！", 31));
            return;
        }
        if (quantity > old) {
            sql = "update books set quantity = " + quantity + " where book_title = '" + title + "'";
            int i = executeUpdate(sql);
            if (i > 0) {
                System.out.println(colorInfo("修改" + title + "数量成功，原数量：" + old + "新数量：" + quantity, 32));
                addLog("修改" + title + "数量成功，原数量：" + old + "新数量：" + quantity, new java.util.Date());
            } else {
                System.out.println(colorInfo("修改" + title + "数量失败", 31));
            }
        } else {
            System.out.println(colorInfo("修改" + title + "数量错误， 输入的数量应该比原来的数量大", 31));
        }
    }

    private List<Book> showAllBooks() throws SQLException, ClassNotFoundException {
        String sql = "select * from books";
        return executeQuery(sql);
    }

    private void showAllLog() {
        String sql = "select * from log";
    }

    private Connection getConn() throws ClassNotFoundException, SQLException {
        // 加载驱动
        Class.forName("com.mysql.cj.jdbc.Driver");
        // 建立连接
        String jdbc_url = "jdbc:mysql://localhost:3306/manager";
        String username = "root";
        String password = "";
        return DriverManager.getConnection(jdbc_url, username, password);
    }

    private void close(Connection connection) {
        if (connection != null) {
            try {
                connection.close();
            } catch (SQLException e) {
                e.printStackTrace();
            }
        }
    }

    private void addLog(String description, java.util.Date date) throws SQLException, ClassNotFoundException {
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        String datetime = sdf.format(date);
        String sql = "insert into log(description, operation_time) values ('" + description + "', '" + datetime + "')";
        int i = executeUpdate(sql);
        if (i > 0) {
            System.out.println(colorInfo("插入日志成功", 32));
        } else {
            System.out.println(colorInfo("插入日志失败", 31));
        }
    }

    private String colorInfo(String content, int color) {
        return String.format("\033[%dm%s\033[0m", color, content);
    }

    public static void main(String[] args) throws SQLException, ClassNotFoundException {
        BookManager manager = new BookManager();
        manager.start();
//        manager.test();
    }
}